package xworker.gluon.glisten.application;

import com.gluonhq.charm.glisten.mvc.View;
import javafx.scene.control.Label;
import org.xmeta.ActionContext;
import org.xmeta.Thing;
import org.xmeta.World;
import org.xmeta.cache.ThingEntry;
import org.xmeta.util.ThingLoader;
import xworker.javafx.util.FXThingLoader;
import xworker.lang.executor.Executor;

import java.util.function.Supplier;

public class ThingViewFactory implements Supplier<View> {
    private static final String TAG = ThingViewFactory.class.getName();
    ThingEntry thingEntry;
    ActionContext actionContext;
    View view;
    Object object;

    public ThingViewFactory(Thing thing, ActionContext parentContext){
        thingEntry = new ThingEntry(thing);
        actionContext = new ActionContext();
        actionContext.put("parentContext", parentContext);
    }

    @Override
    public View get() {
        try {
            if (view == null || thingEntry.isChanged()) {
                Thing viewThing = thingEntry.getThing();
                Thing refThing;
                while((refThing = World.getInstance().getThing(viewThing.getString("viewThing"))) != null){
                    viewThing = refThing;
                }
                Executor.info(TAG, "Create view, viewThing=" + viewThing.getMetadata().getPath());
                Class<?> cls = viewThing.doAction("getClassName", actionContext);
                if (cls != null) {
                    object = cls.getConstructor().newInstance();
                    view = FXThingLoader.load(object, viewThing, actionContext);
                    ThingLoader.init(object);
                }else{
                    view = viewThing.doAction("create", actionContext);
                }

                Executor.info(TAG, "View is created, view=" + view);
            }

            if (view == null) {
                return new View(new Label("No view \nthing=" + thingEntry.getPath()));

            } else {
                return view;
            }
        }catch(Exception e){
            Executor.warn(TAG, "View creat error, view=" + view, e);
            return new View(new Label("Create view exception. \nthing=" + thingEntry.getPath() + "\n" + e.getMessage()));
        }
    }
}
